package org.jdpf.gui.rcp.neteditor.core.blocks;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.jdpf.gui.rcp.neteditor.core.NetEditorActivator;
import org.jdpf.gui.rcp.neteditor.core.elements.AbstractGraphicNode;
import org.jdpf.gui.rcp.neteditor.core.elements.GraphicNetAsTaskValidationStatus;

public class GInspector extends AbstractGraphicNode {
	private static final int DISTANCE_OFFSET = 40;

	private IGraphicBlock inspectorBlock;

	private IGraphicBlock transition;

	public static final String IMAGE_INSPECTOR = "images/insp.png";

	public GInspector(IGraphicBlock transition) {
		this.transition = transition;

		width = 60;
		height = 30;

		Point point = new Point(transition.getOutputPositionPoint(0).x,
				transition.getPosition().y - DISTANCE_OFFSET);

		setPositionCenter(point);
	}

	public void addInspectorBlock(IGraphicBlock inspector) {
		this.inspectorBlock = inspector;
		this.inspectorBlock.setTransitionName("Inspector for "
				+ transition.getTransitionName());

		inspector.attachNode(this);

		inspectorBlock.getGraphicNetValidable().updateValidationStatus();
	}

	public void removeInspectorBlock() {
		this.inspectorBlock = null;
	}

	public IGraphicBlock getInspectorBlock() {
		return this.inspectorBlock;
	}

	public IGraphicBlock getTransitionBlock() {
		return transition;
	}

	public Point getConnectionPosition() {
		Point point = new Point(this.getPosition().x + this.width / 2, this
				.getPosition().y
				+ height);

		return point;
	}

	public boolean isInspectorBlockSet() {
		return inspectorBlock != null;
	}

	public void draw(GC gc) {
		Color white = gc.getDevice().getSystemColor(SWT.COLOR_WHITE);
		Color black = gc.getDevice().getSystemColor(SWT.COLOR_BLACK);
		Color red = gc.getDevice().getSystemColor(SWT.COLOR_RED);
		
		if (inspectorBlock == null) {
			// Draw an empty inspector block

			int OFFSET_X = 5;
			int OFFSET_Y = 7;

			gc.setBackground(white);
			gc.setForeground(black);
			
			gc.fillRoundRectangle(position.x + 1, position.y + 1, width - 1,
					height - 1, 25, 15);
			gc
					.drawRoundRectangle(position.x, position.y, width, height,
							25, 15);

			Font font = new Font(gc.getDevice(), "Arial", 7, SWT.BOLD);
			gc.setFont(font);
			gc.drawText("Drag&Drop", position.x + OFFSET_X, position.y
					+ OFFSET_Y, true);
			font.dispose();

		} else {
			// Draw the inspector

			GraphicNetAsTaskValidationStatus status = inspectorBlock
					.getGraphicNetValidable().getValidationStatus();

			if (inspectorBlock.getTransitionId().equals(
					status.getTransitionIdWithErrors())) {
				gc.setBackground(red);
			} else {
				gc.setBackground(white);
			}
			gc.fillRoundRectangle(position.x + 1, position.y + 1,
					width - 1, height - 1, 25, 15);

			Image image = getImage(IMAGE_INSPECTOR);
			int OFFSET_X = (width / 2) - (image.getBounds().width) / 2;
			int OFFSET_Y = height / 2 - (image.getBounds().height) / 2;

			gc.setForeground(black);
			// gc.setAntialias(SWT.OFF);
			gc
					.drawRoundRectangle(position.x, position.y, width, height,
							25, 15);
			gc.drawImage(image, position.x + OFFSET_X, position.y + OFFSET_Y);
		}
	}

	@Override
	public void setPosition(Point point) {
		super.setPosition(point);

		// GInspector and inspectorBlock positions are always synchronized.
		// The method inspectorBlock.setPosition() is not used cause I'd have
		// a loop: inspectorBlock node is attached to GInspector node.
		if (inspectorBlock != null) {
			inspectorBlock.getPosition().x = point.x;
			inspectorBlock.getPosition().y = point.y;
		}
	}

	private Image getImage(String path) {
		ImageDescriptor desc = AbstractUIPlugin.imageDescriptorFromPlugin(
				NetEditorActivator.PLUGIN_ID, path);
		return desc.createImage();
	}
}
